package com.qq.weixin.common.security;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Map;

import com.hxexp.weixin.common.security.SignatureHelper;

/**
 * 微信签名工具类
 *
 * @author li.jiang
 *
 */
public final class WeixinSignatureUtil {
    private WeixinSignatureUtil() {
    }

    /**
     * 生成微信加密签名
     *
     * @param timestamp
     *            时间戳
     * @param nonce
     *            随机数
     * @return sha1签名
     * @throws Exception
     * @author li.jiang
     * @throws NoSuchAlgorithmException
     */
    public static String generateSignature(String token, String timestamp, String nonce) throws NoSuchAlgorithmException {
        String[] array = new String[] { token, timestamp, nonce };
        StringBuilder sb = new StringBuilder();
        // 字符串排序
        Arrays.sort(array);
        for (int i = 0; i < 3; i++) {
            sb.append(array[i]);
        }
        String str = sb.toString();
        // SHA1签名生成
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        md.update(str.getBytes());
        byte[] digest = md.digest();

        StringBuilder hexstr = new StringBuilder();
        String shaHex = "";
        for (int i = 0; i < digest.length; i++) {
            shaHex = Integer.toHexString(digest[i] & 0xFF);
            if (shaHex.length() < 2) {
                hexstr.append(0);
            }
            hexstr.append(shaHex);
        }
        return hexstr.toString();
    }

    /**
     * 校验微信签名
     *
     *
     * @param signature
     *            微信签名
     * @param token
     *            访问令牌
     * @param timestamp
     *            时间戳
     * @param nonce
     *            随机数
     * @return 校验结果true or false
     * @throws Exception
     * @author li.jiang
     * @throws NoSuchAlgorithmException
     */
    public static boolean checkSignature(String signature, String token, String timestamp, String nonce) throws NoSuchAlgorithmException {
        return signature.equals(generateSignature(token, timestamp, nonce));
    }

    /**
     * 生成支付签名
     *
     * 根据微信支付开发者文档描述的签名算法实现，具体请参考： http://mch.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3
     *
     * @param apiSecretKey
     *            微信支付API密钥
     * @param paramMap
     *            支付参数map
     * @return 支付签名
     */
    public static String generatePaySign(String apiSecretKey, Map<String, String> paramMap) {
        Map<String, String> sortedParamMap = SignatureHelper.sortMapByKey(paramMap);
        String sortedParamStr = sortedParamMap.toString().replaceAll(", ", "&").replaceAll("[{}]", "");
        sortedParamStr += String.format("&key=%s", apiSecretKey);

        return SignatureHelper.encryptMD5(sortedParamStr).toUpperCase();
    }
}
